package Orm.jdbc.connectorPool;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;

/**
 * 连接池管理数据库连接相关工作
 */
public class MyDataSource implements DataSource {

    private final LinkedList<Connection> dataSources = new LinkedList<>();

    /**
     * 初始化创建10个连接
     */
    public MyDataSource(){
        for(int i=0;i<10;i++){
            try {
                Connection conn = JDBCUtils.getConnection();
                // 将连接加入连接池中
                dataSources.add(conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    public Connection getConnection() throws SQLException {
        // 取出连接池中一个连接
        final Connection conn = dataSources.removeFirst(); // 删除第一个连接返回
        System.out.println("取出一个连接剩余 " + dataSources.size() + "个连接！");
        // 将目标Connection对象进行close增强,将close方法逻辑替换为放回连接池
        Connection connProxy = (Connection) Proxy.newProxyInstance(conn
                        .getClass().getClassLoader(), conn.getClass().getInterfaces(),
                new InvocationHandler() {
                    // 执行代理对象任何方法 都将执行 invoke
                    @Override
                    public Object invoke(Object proxy, Method method,
                                         Object[] args) throws Throwable {
                        if (method.getName().equals("close")) {
                            // 需要加强的方法
                            // 不将连接真正关闭，将连接放回连接池
                            releaseConnection(conn);
                            return null;
                        } else {
                            // 不需要加强的方法
                            return method.invoke(conn, args); // 调用真实对象方法
                        }
                    }
                });
        return connProxy;
    }

    // 将连接放回连接池
    public void releaseConnection(Connection conn) {
        dataSources.add(conn);
        System.out.println("将连接 放回到连接池中 数量:" + dataSources.size());
    }

    /**
     * 根据用户名，密码 实时获取连接
     * @param username
     * @param password
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return JDBCUtils.getConnection(username,password);
    }

    /**
     *
     * @param iface
     * @param <T>
     * @return
     * @throws SQLException
     */
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    /**
     *
     * @param iface
     * @return
     * @throws SQLException
     */
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    /**
     *
     * @return
     * @throws SQLException
     */
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    /**
     *
     * @param out
     * @throws SQLException
     */
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
    }

    /**
     *
     * @param seconds
     * @throws SQLException
     */
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    /**
     *
     * @return
     * @throws SQLException
     */
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    /**
     *
     * @return
     * @throws SQLFeatureNotSupportedException
     */
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
